package com.anhtuan.reminder;

import java.util.ArrayList;
import java.util.Calendar;
import java.util.List;

import com.anhtuan.reminder.R;
import com.anhtuan.reminder.dialogs.DayPickerDialog;
import com.anhtuan.reminder.dialogs.DeleteWarningDialog;
import com.anhtuan.reminder.dialogs.TimePickerDialog;
import com.anhtuan.reminder.listelement.AlertListElement;
import com.anhtuan.reminder.listelement.BaseListElement;
import com.anhtuan.reminder.listelement.IncomingCallListElement;
import com.anhtuan.reminder.listelement.OutgoingCallListElement;
import com.anhtuan.reminder.listelement.SendSMSListElement;
import com.anhtuan.reminder.providers.TaskItem;
import com.anhtuan.reminder.providers.TasksProviderWrapper;
import com.anhtuan.reminder.ultils.ActionItem;
import com.anhtuan.reminder.ultils.ListAdapter;
import com.anhtuan.reminder.ultils.RepeatItem;

import android.app.Activity;
import android.app.AlertDialog;
import android.app.ProgressDialog;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.net.Uri;
import android.os.AsyncTask;
import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentActivity;
import android.support.v4.app.FragmentManager;
import android.support.v4.app.FragmentTransaction;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.ViewGroup.LayoutParams;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemSelectedListener;
import android.widget.EditText;
import android.widget.ImageButton;
import android.widget.RadioButton;
import android.widget.Spinner;
import android.widget.ToggleButton;

public class SelectionActivity extends FragmentActivity implements
		OnItemSelectedListener, OnClickListener {

	public static final Uri NEW_ACTION = Uri.parse("action://new");
	public static final Uri EDIT_ACTION = Uri.parse("action://edit");
	public static final Uri DELETE_ACTION = Uri.parse("action://delete");
	public static Uri CURRENT_ACTION = NEW_ACTION;

	private static final int ALERT = ActionItem.ALERT;
	private static final int SEND_SMS = ActionItem.SEND_SMS;
	private static final int OUTGOING_CALL = ActionItem.OUTGOING_CALL;
	private static final int INCOMING_CALL = ActionItem.INCOMING_CALL;
	private static final int FRAGMENT_COUNT = INCOMING_CALL + 1;

	private Fragment[] fragments = new Fragment[FRAGMENT_COUNT];
	private List<BaseListElement> actionList = null;

	private Spinner spinner;
	private ToggleButton tgb_active;
	private ImageButton bt_set_time;
	private ImageButton bt_save;
	private ImageButton bt_delete;
	private ImageButton bt_cancel;
	private EditText et_time;
	private RadioButton rb_not_repeated;
	private RadioButton rb_repeat_weekly;
	private RadioButton rb_repeat_daily;

	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.selection);
		initComponent(savedInstanceState);
	}

	private void initComponent(Bundle savedInstanceState) {
		// Find views
		spinner = (Spinner) findViewById(R.id.sp_action);
		
		tgb_active = (ToggleButton) findViewById(R.id.tgb_active);
		// Hide the active toggle button
		tgb_active.getLayoutParams().height = 0;
		tgb_active.getLayoutParams().width = 0;
		
		
		bt_set_time = (ImageButton) findViewById(R.id.bt_set_time);
		bt_save = (ImageButton) findViewById(R.id.bt_selection_save);
		bt_delete = (ImageButton) findViewById(R.id.bt_selection_delete);
		bt_cancel = (ImageButton) findViewById(R.id.bt_selection_cancel);

		et_time = (EditText) findViewById(R.id.et_time);
		rb_not_repeated = (RadioButton) findViewById(R.id.rb_not_repeated);
		rb_repeat_weekly = (RadioButton) findViewById(R.id.rb_repeat_weekly);
		rb_repeat_daily = (RadioButton) findViewById(R.id.rb_repeat_daily);

		// Initiate Fragments
		FragmentManager fm = getSupportFragmentManager();
		fragments[ALERT] = fm.findFragmentById(R.id.alert_fragment);
		fragments[SEND_SMS] = fm.findFragmentById(R.id.sendsms_fragment);
		fragments[OUTGOING_CALL] = fm
				.findFragmentById(R.id.outgoing_call_fragment);
		fragments[INCOMING_CALL] = fm
				.findFragmentById(R.id.incoming_call_fragment);

		FragmentTransaction transaction = fm.beginTransaction();
		for (int i = 0; i < fragments.length; i++) {
			transaction.hide(fragments[i]);
		}
		transaction.commit();

		// Initiate spinner items
		actionList = new ArrayList<BaseListElement>();
		actionList.add(new AlertListElement(this, ALERT));
		actionList.add(new SendSMSListElement(this, SEND_SMS));
		actionList.add(new OutgoingCallListElement(this, OUTGOING_CALL));
		actionList.add(new IncomingCallListElement(this, INCOMING_CALL));

		ListAdapter adapter = new ListAdapter(this,
				android.R.layout.simple_spinner_item, actionList);
		adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
		spinner.setAdapter(adapter);
		spinner.setOnItemSelectedListener(this);

		// Set listener for views
		bt_set_time.setOnClickListener(this);
		bt_save.setOnClickListener(this);
		bt_delete.setOnClickListener(this);
		bt_cancel.setOnClickListener(this);
		rb_not_repeated.setOnClickListener(this);
		rb_repeat_weekly.setOnClickListener(this);
		rb_repeat_daily.setOnClickListener(this);

		CURRENT_ACTION = getIntent().getData();

		if (CURRENT_ACTION.equals(NEW_ACTION)) {
			rb_not_repeated.setChecked(true);
			bt_delete.setEnabled(false);
		} else if (CURRENT_ACTION.equals(EDIT_ACTION)) {
			
			// Show the active toggle button
			tgb_active.getLayoutParams().height = LayoutParams.WRAP_CONTENT;
			tgb_active.getLayoutParams().width = LayoutParams.WRAP_CONTENT;
			
			int taskId = getIntent().getExtras().getInt(
					MainActivity.TASK_ID_KEY);
			LoadTask loadTask = new LoadTask(this, taskId);
			loadTask.execute();
		}
	}

	// Spinner selected changed listener
	@Override
	public void onItemSelected(AdapterView<?> parent, View view, int pos,
			long id) {
		showFragment(pos, false);
	}

	// Spinner selected changed listener
	@Override
	public void onNothingSelected(AdapterView<?> parent) {
	}

	private int repeat = RepeatItem.NOT_REPEATED;
	public static int day = Calendar.getInstance().get(Calendar.DAY_OF_WEEK); // Maybe changed in day picker dialog
	
	// Buttons onClick Listener
	@Override
	public void onClick(View view) {
		// TODO Auto-generated method stub
		int id = view.getId();

		switch (id) {
		
		case R.id.bt_set_time:
			// Set time
			
			TimePickerDialog timePickerDialog = new TimePickerDialog();
			timePickerDialog.show(getSupportFragmentManager(), "TimePickerDialog");
			break;

		case R.id.bt_selection_save:
			// Save
			
			SaveTask saveTask = new SaveTask(this);
			saveTask.execute();

			break;

		case R.id.bt_selection_delete:
			// Delete
			
			DialogInterface.OnClickListener onClickListener = new DialogInterface.OnClickListener() {
				
				@Override
				public void onClick(DialogInterface dialog, int which) {
					
					int id = getIntent().getExtras().getInt(MainActivity.TASK_ID_KEY);
					
					// Remove from database
					TasksProviderWrapper.deleteRecordById(getContentResolver(), id);
					
					// Send message to main activity to remove task
					Intent intent = new Intent();
					intent.setData(DELETE_ACTION);
					intent.putExtra(MainActivity.TASK_ID_KEY, id);
					setResult(RESULT_OK, intent);
					finish();
				}
			};
			
			DeleteWarningDialog deleteWarningDialog = new DeleteWarningDialog();
			deleteWarningDialog.setPositiveButtonOnClickListener(onClickListener);
			deleteWarningDialog.setNegativeButtonOnClickListener(null);
			deleteWarningDialog.show(getSupportFragmentManager(), deleteWarningDialog.getTag());
			
			break;
			
		case R.id.bt_selection_cancel:
			// Cancel
			
			setResult(Activity.RESULT_CANCELED);
			finish();
			break;

		case R.id.rb_not_repeated:
			// Radio button Not repeated
			
			repeat = RepeatItem.NOT_REPEATED;
			break;
			
		case R.id.rb_repeat_weekly:
			// Radio button repeat weekly
			
			repeat = RepeatItem.REPEAT_WEEKLY;

			DayPickerDialog dayPickerDialog = new DayPickerDialog();
			dayPickerDialog.show(getSupportFragmentManager(), dayPickerDialog.getTag());

			break;
			
		case R.id.rb_repeat_daily:
			// Radio button repeat daily
			
			repeat = RepeatItem.REPEAT_DAILY;
			
			break;
			
		default:
			break;
		}
	}
	
	// Show the fragment following the action
	public void showFragment(int fragmentIndex, boolean addToBackStack) {
		FragmentManager fm = getSupportFragmentManager();
		FragmentTransaction transaction = fm.beginTransaction();
		for (int i = 0; i < fragments.length; i++) {
			if (i == fragmentIndex) {
				transaction.show(fragments[i]);
			} else {
				transaction.hide(fragments[i]);
			}
		}

		if (addToBackStack) {
			transaction.addToBackStack(null);
		}
		transaction.commit();
	}

	// Check input fields
	public boolean allFieldsAreValid() {
		EditText editText;

		if (et_time.getText().toString().trim().equals("")) {
			return false;
		}

		switch (spinner.getSelectedItemPosition()) {
		
		case ALERT:
			editText = (EditText) findViewById(R.id.et_alert_msg);
			
			if (editText.getText().toString().trim().equals("")) {
				return false;
			}
			
			break;
		case SEND_SMS:
			editText = (EditText) findViewById(R.id.et_sms_contact);

			if (editText.getText().toString().trim().equals("")) {
				return false;
			}

			editText = (EditText) findViewById(R.id.et_sms_content);

			if (editText.getText().toString().trim().equals("")) {
				return false;
			}

			break;

		case OUTGOING_CALL:
			editText = (EditText) findViewById(R.id.et_call_contact);

			if (editText.getText().toString().trim().equals("")) {
				return false;
			}

			break;
			
		case INCOMING_CALL:
			
			editText = (EditText) findViewById(R.id.et_callme_contact);
			
			if (editText.getText().toString().trim().equals("")) {
				return false;
			}
			
			break;
		default:
			break;
		}

		return true;
	}

	// Load task
	private class LoadTask extends AsyncTask<Void, Void, Void> {
		private ProgressDialog progressDialog;
		private int taskId;
		private TaskItem taskItem = null;

		public LoadTask(Context context, int taskId) {
			progressDialog = new ProgressDialog(context);
			this.taskId = taskId;
		}

		@Override
		protected void onPreExecute() {
			progressDialog.setMessage(getResources().getString(R.string.progress_dialog_loading_text));
			progressDialog.show();
		}

		@Override
		protected void onPostExecute(Void result) {
			if (progressDialog.isShowing()) {
				
				try {
					Thread.sleep(50);
				} catch (InterruptedException e) {
					e.printStackTrace();
				}
				
				progressDialog.dismiss();
			}
		}

		@Override
		protected Void doInBackground(Void... params) {
			taskItem = TasksProviderWrapper.getTaskById(getContentResolver(),
					taskId);
			this.publishProgress();

			return null;
		}

		@Override
		protected void onProgressUpdate(Void... values) {
			if (taskItem != null) {
				
				// Set selected for spinner
				spinner.setSelection(taskItem.getAction(), true);
				
				// Fill in edit text time
				et_time.setText(taskItem.getFirstContent());
				
				day = taskItem.getDay();
				repeat = taskItem.getRepeat();
				
				// Set active toggle button
				tgb_active.setChecked(taskItem.isActive());
				
				// Fill in edit text of each fragment
				switch (taskItem.getAction()) {
				case ALERT:
					EditText et_alert_msg = (EditText) findViewById(R.id.et_alert_msg);
					et_alert_msg.setText(taskItem.getSecContent());
					
					break;
				
				case SEND_SMS:
					EditText et_sms_contact = (EditText) findViewById(R.id.et_sms_contact);
					EditText et_sms_content = (EditText) findViewById(R.id.et_sms_content);

					et_sms_contact.setText(taskItem.getSecContent());
					et_sms_content.setText(taskItem.getThirdContent());

					break;

				case OUTGOING_CALL:
					EditText et_call_contact = (EditText) findViewById(R.id.et_call_contact);
					et_call_contact.setText(taskItem.getSecContent());
					break;

				case INCOMING_CALL:
					EditText et_callme_contact = (EditText) findViewById(R.id.et_callme_contact);
					et_callme_contact.setText(taskItem.getSecContent());
					
					break;
				default:
					break;
				}

				// Set checked for radio buttons
				switch (taskItem.getRepeat()) {
				case RepeatItem.NOT_REPEATED:
					rb_not_repeated.setChecked(true);
					break;

				case RepeatItem.REPEAT_WEEKLY:
					rb_repeat_weekly.setChecked(true);
					rb_repeat_weekly.setText(getResources().getString(R.string.repeat_weekly_text) + " " +
										String.format(getResources().getString(
														R.string.repeat_weekly_text_format,
														getResources().getStringArray(R.array.dayofweek)[taskItem.getDay() - 1])));
					break;

				case RepeatItem.REPEAT_DAILY:
					rb_repeat_daily.setChecked(true);
					break;

				default:
					break;
				}
			}
		}
	}

	// Save task
	private class SaveTask extends AsyncTask<Void, Void, Void> {
		private ProgressDialog progressDialog;
		private ReminderApplication application;
		private TaskItem taskItem = null;
		private boolean valid = false;
		
		public SaveTask(Context context) {
			progressDialog = new ProgressDialog(context);
			application = (ReminderApplication) getApplication();
		}

		@Override
		protected void onPreExecute() {
			progressDialog.setMessage(getResources().getString(R.string.progress_dialog_saving_text));
			progressDialog.show();
		}

		@Override
		protected void onPostExecute(Void result) {
			if (progressDialog.isShowing()) {
				
				try {
					Thread.sleep(50);
				} catch (InterruptedException e) {
					e.printStackTrace();
				}
				
				progressDialog.dismiss();
			}
			
			if (taskItem != null) {
				if (valid) {
					if (CURRENT_ACTION.equals(NEW_ACTION)) {
						TasksProviderWrapper.insertRowRecord(
								getContentResolver(), taskItem);
						taskItem.setId(TasksProviderWrapper
								.getLastestId(getContentResolver()));
					} else if (CURRENT_ACTION.equals(EDIT_ACTION)) {
						taskItem.setId(getIntent().getExtras().getInt(
								MainActivity.TASK_ID_KEY));
						
						ToggleButton tgb = (ToggleButton) findViewById(R.id.tgb_active);
						taskItem.setActive(tgb.isChecked());
						
						TasksProviderWrapper.updateRowRecord(
								getContentResolver(), taskItem);
					}

					application.setTaskItem(taskItem);

					Intent intent = new Intent();
					intent.setData(CURRENT_ACTION);

					setResult(RESULT_OK, intent);
					finish();
				} else {
					
				}
			}
		}

		@Override
		protected Void doInBackground(Void... params) {
			
			if (valid = allFieldsAreValid()) {
			
				int actionId = spinner.getSelectedItemPosition();
				switch (actionId) {
	
				case ALERT:
					EditText et_alert_msg = (EditText) fragments[ALERT].getView().findViewById(R.id.et_alert_msg);
					
					taskItem = new TaskItem(true, ALERT, repeat, day, et_time.getText().toString(), et_alert_msg.getText().toString(), null);
					
					break;
	
				case SEND_SMS:
					EditText et_sms_contact = (EditText) fragments[SEND_SMS]
							.getView().findViewById(R.id.et_sms_contact);
					EditText et_content = (EditText) fragments[SEND_SMS].getView()
							.findViewById(R.id.et_sms_content);
	
					taskItem = new TaskItem(true, SEND_SMS, repeat, day, et_time
							.getText().toString(), et_sms_contact.getText()
							.toString(), et_content.getText().toString());
					break;
	
				case OUTGOING_CALL:
					EditText et_call_contact = (EditText) fragments[OUTGOING_CALL]
							.getView().findViewById(R.id.et_call_contact);
	
					taskItem = new TaskItem(true, OUTGOING_CALL, repeat, day, et_time
							.getText().toString(), et_call_contact.getText()
							.toString(), null);
					break;
	
				case INCOMING_CALL:
					EditText et_callme_contact = (EditText) fragments[INCOMING_CALL]
							.getView().findViewById(R.id.et_callme_contact);
					
					taskItem = new TaskItem(true, INCOMING_CALL, repeat, day, et_time
							.getText().toString(), et_callme_contact.getText().toString(), null);
	
					break;
				default:
					break;
				}
				
			} else {
				//  Some fill invalid, publish to foreground thread
				publishProgress();
			}
			
			return null;
		}

		@Override
		protected void onProgressUpdate(Void... values) {
			AlertDialog.Builder builder = new AlertDialog.Builder(
					SelectionActivity.this);
			builder.setMessage("Some field invalid")
					.setPositiveButton(R.string.picker_button_ok_text, null);

			builder.create().show();
		}
	}
}
